#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
逐步调试排列5预测功能
"""

import sys
import os
import torch
import numpy as np
from PyQt5.QtWidgets import QApplication

# 添加项目根目录到路径
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.append(project_root)

def debug_lstm_crf_prediction():
    """逐步调试LSTM-CRF预测"""
    print("\n" + "="*60)
    print(" 逐步调试LSTM-CRF预测")
    print("="*60)
    
    try:
        from lottery_predictor_app import LotteryPredictorApp, load_resources_pytorch
        from algorithms.plw_sequence_lstm import PLWDataProcessor
        
        # 创建应用实例
        app = QApplication.instance()
        if app is None:
            app = QApplication(sys.argv)
            
        predictor = LotteryPredictorApp()
        print("[INFO] 成功创建LotteryPredictorApp实例")
        
        # 1. 检查模型加载
        print("\n1. 检查模型加载...")
        try:
            plw_model, blue_model, scaler_X = load_resources_pytorch("plw")
            print(f"[INFO] 模型加载成功")
            print(f"   模型类型: {type(plw_model)}")
            print(f"   LSTM输入维度: {plw_model.lstm.input_size}")
            print(f"   LSTM隐藏维度: {plw_model.lstm.hidden_size}")
            print(f"   输出维度: {plw_model.output_dim}")
            print(f"   输出序列长度: {plw_model.output_seq_length}")
        except Exception as e:
            print(f"[ERROR] 模型加载失败: {e}")
            return False
        
        # 2. 检查数据处理
        print("\n2. 检查数据处理...")
        try:
            csv_file = os.path.join(project_root, 'scripts', 'plw', 'plw_history.csv')
            processor = PLWDataProcessor(csv_file, window_size=10)
            recent_data = processor.get_recent_data()
            print(f"✅ 数据处理成功")
            print(f"   最近数据形状: {recent_data.shape if recent_data is not None else 'None'}")
            if recent_data is not None:
                print(f"   数据示例: {recent_data[0, -1, :5].tolist()}")
        except Exception as e:
            print(f" 数据处理失败: {e}")
            return False
        
        # 3. 检查输入数据准备
        print("\n3. 检查输入数据准备...")
        try:
            if recent_data is not None:
                # 准备输入数据 - LSTM-CRF模型只需要前5个数字特征
                if recent_data.shape[-1] == 10:  # 如果是带区域转换特征的数据
                    input_data = recent_data[:, :, :5]  # 只取前5个数字特征
                else:
                    input_data = recent_data
                
                # 添加batch维度
                if len(input_data.shape) == 2:
                    input_data = input_data.unsqueeze(0)
                
                print(f"[INFO] 输入数据准备成功")
                print(f"   输入数据形状: {input_data.shape}")
                print(f"   输入数据示例: {input_data[0, -1, :].tolist()}")
                
                # 检查输入维度是否匹配模型期望
                expected_input_dim = plw_model.lstm.input_size
                actual_input_dim = input_data.shape[-1]
                print(f"   期望输入维度: {expected_input_dim}")
                print(f"   实际输入维度: {actual_input_dim}")
                
                if actual_input_dim != expected_input_dim:
                    print(f"[WARNING] 输入维度不匹配，需要调整")
                    if actual_input_dim > expected_input_dim:
                        input_data = input_data[:, :, :expected_input_dim]
                    else:
                        # 用0填充
                        padding = torch.zeros(input_data.shape[0], input_data.shape[1], 
                                            expected_input_dim - actual_input_dim)
                        input_data = torch.cat([input_data, padding], dim=-1)
                    print(f"   调整后输入数据形状: {input_data.shape}")
            else:
                print(" 最近数据为空")
                return False
        except Exception as e:
            print(f" 输入数据准备失败: {e}")
            return False
        
        # 4. 检查模型预测
        print("\n4. 检查模型预测...")
        try:
            # 确保输入数据与模型在同一设备上
            device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
            plw_model = plw_model.to(device)
            input_data = input_data.to(device)
            
            print(f"   模型设备: {next(plw_model.parameters()).device}")
            print(f"   数据设备: {input_data.device}")
            
            # 使用模型预测
            plw_model.eval()
            with torch.no_grad():
                plw_predictions = plw_model(input_data)
            
            print(f"[INFO] 模型预测完成")
            print(f"   预测结果类型: {type(plw_predictions)}")
            print(f"   预测结果: {plw_predictions}")
            
            if isinstance(plw_predictions, list) and len(plw_predictions) > 0:
                predicted_sequence = plw_predictions[0]  # 第一个样本的预测
                print(f"   预测序列: {predicted_sequence}")
            else:
                print("[WARNING] 模型返回格式异常")
                return False
                
        except Exception as e:
            print(f" 模型预测失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        return True
        
    except Exception as e:
        print(f" 调试失败: {e}")
        import traceback
        traceback.print_exc()
        return False

def debug_enhanced_lstm_prediction():
    """逐步调试序列LSTM增强模式预测"""
    print("\n" + "="*60)
    print(" 逐步调试序列LSTM增强模式预测")
    print("="*60)
    
    try:
        from algorithms.simple_plw_lstm import load_simple_plw_sequence_model
        from algorithms.plw_sequence_lstm import PLWDataProcessor
        
        # 1. 检查模型加载
        print("\n1. 检查模型加载...")
        try:
            model_path = os.path.join(project_root, 'scripts', 'plw', 'plw_sequence_lstm_model.pth')
            device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
            plw_model = load_simple_plw_sequence_model(model_path, device)
            print(f"✅ 模型加载成功")
            print(f"   模型类型: {type(plw_model)}")
            print(f"   模型设备: {next(plw_model.parameters()).device}")
        except Exception as e:
            print(f" 模型加载失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        # 2. 检查数据处理
        print("\n2. 检查数据处理...")
        try:
            csv_file = os.path.join(project_root, 'scripts', 'plw', 'plw_history.csv')
            processor = PLWDataProcessor(csv_file, window_size=10)
            recent_data = processor.get_recent_data()
            print(f"✅ 数据处理成功")
            print(f"   最近数据形状: {recent_data.shape if recent_data is not None else 'None'}")
            if recent_data is not None:
                print(f"   数据示例: {recent_data[0, -1, :5].tolist()}")
        except Exception as e:
            print(f" 数据处理失败: {e}")
            return False
        
        # 3. 检查输入数据准备
        print("\n3. 检查输入数据准备...")
        try:
            if recent_data is not None:
                # 简化版模型只需要前5个数字特征
                if recent_data.shape[-1] == 10:  # 如果是带区域转换特征的数据
                    input_data = recent_data[:, :, :5]  # 只取前5个数字特征
                else:
                    input_data = recent_data
                
                # 确保数据在正确的设备上
                input_data = input_data.to(device)
                
                print(f"✅ 输入数据准备成功")
                print(f"   输入数据形状: {input_data.shape}")
                print(f"   输入数据示例: {input_data[0, -1, :].tolist()}")
            else:
                print(" 最近数据为空")
                return False
        except Exception as e:
            print(f" 输入数据准备失败: {e}")
            return False
        
        # 4. 检查模型预测
        print("\n4. 检查模型预测...")
        try:
            # 使用真实模型预测
            with torch.no_grad():
                predictions_tensor, probabilities = plw_model.predict(input_data)
            
            print(f"✅ 模型预测完成")
            print(f"   预测张量形状: {predictions_tensor.shape}")
            print(f"   概率张量形状: {probabilities.shape}")
            print(f"   预测结果: {predictions_tensor[0].tolist()}")
            print(f"   最大概率: {torch.max(probabilities[0]).item():.4f}")
            
        except Exception as e:
            print(f" 模型预测失败: {e}")
            import traceback
            traceback.print_exc()
            return False
        
        return True
        
    except Exception as e:
        print(f" 调试失败: {e}")
        import traceback
        traceback.print_exc()
        return False

if __name__ == "__main__":
    print("🚀 开始逐步调试排列5预测功能")
    
    print("\n" + "="*80)
    print("🔬 LSTM-CRF预测调试")
    print("="*80)
    lstm_crf_success = debug_lstm_crf_prediction()
    
    print("\n" + "="*80)
    print("🔬 序列LSTM增强模式预测调试")
    print("="*80)
    enhanced_success = debug_enhanced_lstm_prediction()
    
    print("\n" + "="*80)
    print("🏁 调试结果总结")
    print("="*80)
    print(f"LSTM-CRF预测: {'✅ 成功' if lstm_crf_success else '❌ 失败'}")
    print(f"序列LSTM增强模式预测: {'✅ 成功' if enhanced_success else '❌ 失败'}")
    
    if lstm_crf_success and enhanced_success:
        print("\n🎉 所有调试测试通过！")
    else:
        print("\n⚠️  部分调试测试失败，请检查上述错误信息。")